<?php
/**
 *
 */
namespace App\Controller;

use App\Common;
use App\EntryService;
use App\Service\BindService;
use App\Service\FriendService;
use App\Service\GetmsgService;
use App\Service\GroupService;
use App\Service\PingService;
use App\Service\SendgroupService;
use App\Service\SendtextService;
use App\WebSoketBaseController;
use Hyperf\Contract\OnCloseInterface;
use Hyperf\Contract\OnMessageInterface;
use Hyperf\Contract\OnOpenInterface;
use Swoole\Http\Request;
use Swoole\Http\Response;
use Swoole\WebSocket\Frame;
use Swoole\WebSocket\Server;
use Hyperf\Di\Annotation\Inject;

class WebSocketController extends WebSoketBaseController implements OnMessageInterface,OnOpenInterface,OnCloseInterface
{
    /**
     * @Inject
     * @var Common
     */
    private $_common;

    /**
     * @Inject
     * @var BindService
     */
    private $_bindService;

    /**
     * @Inject
     * @var SendtextService
     */
    private $_sendtextService;

    /**
     * @Inject
     * @var GroupService
     */
    private $_groupService;

    /**
     * @Inject
     * @var SendgroupService
     */
    private $_sendgroupService;

    /**
     * @Inject
     * @var GetmsgService
     */
    private $_getmsgService;

    /**
     * @Inject
     * @var FriendService
     */
    private $_friendService;

    /**
     * @Inject
     * @var PingService
     */
    private $_pingService;


    /**
     * 建立连接
     * @param Response|Server $server
     * @param Request $request
     */
    public function onOpen($server, Request $request): void
    {
        echo '收到open = '.$request->fd . PHP_EOL;

        $get = $request->get;

        // 前端客户端连接需要校验
        if (!isset($get['from']) || $get['from'] !== 'server')
        {
            $result_msg = 'init success';
            $tag =  'init';
            if ($res_msg = $this->_bindService->authCheck($get['appid'] ?? '')){
                $server->push($request->fd, $this->res_json(-1,[],$res_msg));
                $server->disconnect($request->fd);
            }

            if (isset($get['account']) && !empty($get['account'])){
                // 绑定
                $res_bind = (new BindService($server,$request->fd,$get))->init();
                $result_msg .= ' ' . $res_bind[1];
                $tag = 'bind';
            }

            $server->push($request->fd, $this->res_json(0,[],$result_msg,$tag));
        }

    }

    /**
     * 接收消息
     * @param Response|Server $server
     * @param Frame $frame
     */
    public function onMessage($server, Frame $frame): void
    {
        echo '收到Message = '.$frame->fd.'='.$frame->data.PHP_EOL;
        if (!$frame->data) return;

        $res = $this->_common->is_json($frame->data);
        if ($res){
            $server->push($frame->fd, $this->res_json(-200,[],$res));
            return;
        }

        $data_arr = json_decode($frame->data,true);

        if (!isset($data_arr['appid']) || !$data_arr['appid'])
        {
            $server->push($frame->fd, $this->res_json(-201,$data_arr,'appid 有误'));
            return;
        }
        $appid = $data_arr['appid'];

        if (!isset($data_arr['tag']) || !$data_arr['tag'])
        {
            $server->push($frame->fd, $this->res_json(-201,$data_arr,'tag 不能为空'));
            return;
        }

        if (!isset($data_arr['data']) || !$data_arr['data'])
            $data_arr['data'] = [];

        if (!is_array($data_arr['data']))
        {
            $server->push($frame->fd, $this->res_json(-201,$data_arr,'data 的数据类型有误'));
            return;
        }

        $data   = $data_arr['data'] ?? [];
        $action = $data['action'] ?? '';
        $data['appid']   = $appid;
        $data['tag']     = $data_arr['tag'];
        $data['account'] = $data_arr['account'] ?? '';

        $tag_event = new EntryService($server, $frame->fd, $data['tag'], $data);
        $server->push($frame->fd, $this->res_json($tag_event->_code,$tag_event->_res_data,$tag_event->_msg,$data['tag'],$action));
    }

    /**
     * 断开连接
     * @param Response|\Swoole\Server $server
     * @param int $fd
     * @param int $reactorId
     */
    public function onClose($server, int $fd, int $reactorId): void
    {
        $res = $this->_bindService->unBind($fd);
        echo $fd . '下线了：' . $res . ' reactorId='.$reactorId . PHP_EOL;
    }
}